package io.dcloud.uniplugin;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.io.File;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

import uni.dcloud.io.uniplugin_video.R;

public class VideoActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private SurfaceView surfaceView;
    private MediaRecorder mRecorder;
    SurfaceHolder mSurfaceHolder;
    private Camera mCamera;
    private Camera.Parameters parameters;
    private ImageView mFlashbulb;
    private ImageView btnOk;
    private ImageView btnClose;
    private ImageView btnRecord;
    private ImageView thumb;
    private String path;
    private int maxDuration = 15;//录制最长时间为15秒
    //分辨率
    private int width = 1920;
    private int height = 1080;

    private int rotationRecord = 90;//视频旋转角度
    private int rotationFlag = 0;
    OrientationEventListener mOrientationListener;//监测指定的屏幕旋转角度

    private boolean openFlashbulb = false;
    private int state = 0;//录制状态 0未录制  1录制中  2录制完成
    private int text = 0;
    private TextView time;
    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            text++;
            String str = "00:00";
            if (text < 10) {
                str = "00:0" + text;
            } else if (text < 60) {
                str = "00:" + text;
            } else {
                if (text / 60 < 10) {
                    str = "0" + text / 60 + ":" + text % 60;
                } else {
                    str = text / 60 + ":" + text % 60;
                }
            }
            time.setText(str);
            handler.postDelayed(this, 1000);
            if (text > maxDuration) {
                stopRecord();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);
        time = findViewById(R.id.time);
        thumb = findViewById(R.id.thumb);
        mFlashbulb = findViewById(R.id.flashbulb);
        mFlashbulb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (openFlashbulb) {
                    setFlashMode(false);//关闭闪光灯
                    mFlashbulb.setImageResource(R.drawable.ic_sgd_c);
                } else {
                    setFlashMode(true);//打开闪光灯
                    mFlashbulb.setImageResource(R.drawable.ic_sgd);
                }
            }
        });
        btnOk = findViewById(R.id.btnOk);
        btnOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.putExtra("videoPath", path);
                setResult(VideoModule.REQUEST_CODE, intent);
                finish();
            }
        });
        btnClose = findViewById(R.id.btnClose);
        btnClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (state == 0 || state == 1) {
                    finish();
                } else {
                    File file = new File(path);
                    if (file.exists()) {
                        file.delete();
                        path = "";
                    }
                    state = 0;
                    setBntState();
                    //surfaceView.setBackground(null);
                    surfaceView.getBackground().setAlpha(0);
                    thumb.setVisibility(View.GONE);
                    setCameraPreview(mSurfaceHolder);
                }
            }
        });
        btnRecord = findViewById(R.id.btnRecord);
        btnRecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (state == 0) {
                    startRecord();
                } else if (state == 1) {
                    stopRecord();
                } else {
                    Intent it = new Intent(Intent.ACTION_VIEW);
                    it.setDataAndType(Uri.parse(path), "video/mp4");
                    startActivity(it);
                }
            }
        });
        surfaceView = findViewById(R.id.surfaceview);
        surfaceView.setFocusable(true);//自动对焦
        mSurfaceHolder = surfaceView.getHolder();
        //根据比例设置surface的宽度
        mSurfaceHolder.setFixedSize(height, width);

        mSurfaceHolder.setFormat(PixelFormat.TRANSPARENT);
        // 如果需要，保持屏幕常亮
        mSurfaceHolder.setKeepScreenOn(true);
        mSurfaceHolder.addCallback(this);
        mOrientationListener = new OrientationEventListener(this) {
            @Override
            public void onOrientationChanged(int rotation) {
                if (state == 0 || state == 2) {
                    if (((rotation >= 0) && (rotation <= 30)) || (rotation >= 330)) {
                        // 竖屏拍摄
                        if (rotationFlag != 0) {
                            //旋转logo
                            rotationAnimation(rotationFlag, 0);
                            //这是竖屏视频需要的角度
                            rotationRecord = 90;
                            //这是记录当前角度的flag
                            rotationFlag = 0;
                        }
                    } else if (((rotation >= 230) && (rotation <= 310))) {
                        // 横屏拍摄
                        if (rotationFlag != 90) {
                            //旋转logo
                            rotationAnimation(rotationFlag, 90);
                            //这是正横屏视频需要的角度
                            rotationRecord = 0;
                            //这是记录当前角度的flag
                            rotationFlag = 90;
                        }
                    } else if (rotation > 30 && rotation < 95) {
                        // 反横屏拍摄
                        if (rotationFlag != 270) {
                            //旋转logo
                            rotationAnimation(rotationFlag, 270);
                            //这是反横屏视频需要的角度
                            rotationRecord = 180;
                            //这是记录当前角度的flag
                            rotationFlag = 270;
                        }
                    }
                    //倒过来就算了，你又不是小米MIX
                }
            }
        };
        mOrientationListener.enable();
    }

    private void rotationAnimation(int rotation1, int rotation2) {
//        rotationView(mFlashbulb, rotation1, rotation2);
//        rotationView(btnOk, rotation1, rotation2);
//        rotationView(btnClose, rotation1, rotation2);
//        rotationView(btnRecord, rotation1, rotation2);
    }

    private void rotationView(View view, int rotation1, int rotation2) {
        ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(view, "rotation", (float) rotation1, (float) rotation2);
        rotateAnimation.setDuration(500);
        rotateAnimation.start();
    }

    private void setCameraPreview(SurfaceHolder surfaceHolder) {
        initCamera();
        setCameraDisplayOrientation(VideoActivity.this, 0, mCamera);
        try {
            mCamera.setPreviewDisplay(surfaceHolder);//通过SurfaceView显示取景画面
            //此处也可以设置摄像头参数
            /**
             WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//得到窗口管理器
             Display display  = wm.getDefaultDisplay();//得到当前屏幕
             Camera.Parameters parameters = camera.getParameters();//得到摄像头的参数
             parameters.setPictureFormat(PixelFormat.RGB_888);//设置照片的格式
             parameters.setJpegQuality(85);//设置照片的质量
             parameters.setPictureSize(display.getHeight(), display.getWidth());//设置照片的大小，默认是和     屏幕一样大
             camera.setParameters(parameters);//设置需要预览的尺寸
             **/
        } catch (IOException e) {
            Log.e("TAG", e.toString());
        }
    }

    /**
     * 设置 摄像头的角度
     *
     * @param activity 上下文
     * @param cameraId 摄像头ID（假如手机有N个摄像头，cameraId 的值 就是 0 ~ N-1）
     * @param camera   摄像头对象
     */
    public static void setCameraDisplayOrientation(Activity activity,
                                                   int cameraId, android.hardware.Camera camera) {

        Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        //获取摄像头信息
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

        //获取摄像头当前的角度
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            //前置摄像头
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
        } else {
            // back-facing  后置摄像头
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

    //初始化相机
    private void initCamera() {
        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);//打开硬件摄像头，这里导包得时候一定要注意是android.hardware.Camera
        parameters = mCamera.getParameters();
        if (!Build.MODEL.equals("KORIDY H30")) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 1连续对焦
        } else {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        }
        mCamera.setParameters(parameters);
        mCamera.startPreview();
        mCamera.cancelAutoFocus();// 2如果要实现连续的自动对焦，这一句必须加上
    }

    //释放相机
    private void releaseCamera() {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }

    //切换闪光灯
    private void setFlashMode(boolean isOpen) {
        openFlashbulb = isOpen;
        String flashMode = Camera.Parameters.FLASH_MODE_OFF;
        if (isOpen) {
            flashMode = Camera.Parameters.FLASH_MODE_TORCH;
        }
        parameters.setFlashMode(flashMode);
        mCamera.setParameters(parameters);
    }

    private void setBntState() {
        int img;
        if (state == 0) {
            img = R.drawable.ic_record;
            mFlashbulb.setVisibility(View.VISIBLE);
            btnOk.setVisibility(View.GONE);
        } else if (state == 1) {
            img = R.drawable.ic_recording;
            mFlashbulb.setVisibility(View.VISIBLE);
            btnOk.setVisibility(View.GONE);
        } else {
            img = R.drawable.ic_play;
            mFlashbulb.setVisibility(View.GONE);
            btnOk.setVisibility(View.VISIBLE);
        }
        btnRecord.setImageResource(img);
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mSurfaceHolder = holder;
        if (state == 0) {
            setCameraPreview(holder);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mSurfaceHolder = holder;
        ViewGroup.LayoutParams params = thumb.getLayoutParams();
        params.width = width;
        params.height = height;
        thumb.setLayoutParams(params);
        if (mCamera != null) {
            // 实现自动对焦
            mCamera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                        camera.cancelAutoFocus();// 只有加上了这一句，才会自动对焦
                        doAutoFocus();
                    }
                }
            });
        }
    }

    private void doAutoFocus() {
        parameters = mCamera.getParameters();
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        mCamera.setParameters(parameters);
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    camera.cancelAutoFocus();// 只有加上了这一句，才会自动对焦。
                    if (!Build.MODEL.equals("KORIDY H30")) {
                        parameters = camera.getParameters();
                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 1连续对焦
                        camera.setParameters(parameters);
                    } else {
                        parameters = camera.getParameters();
                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                        camera.setParameters(parameters);
                    }
                }
            }
        });
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (state == 1) {
            stopRecord();
        } else if (state == 0) {
            if (mCamera != null) {
                releaseCamera();
            }
        }
    }

    private void startRecord() {
        if (mRecorder == null) {
            mRecorder = new MediaRecorder();// 创建mediarecorder对象
            try {
                if (mCamera != null) {
                    mCamera.unlock();
                    mRecorder.setCamera(mCamera);// 设置录制视频源为Camera(相机)
                }
                mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); // 这两项需要放在setOutputFormat之前
                mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 这两项需要放在setOutputFormat之前
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置录制视频的输出格式
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频编码格式
                mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码格式// 设置录制的视频编码h263 h264
                mRecorder.setVideoSize(width, height);//设置视频的分辨率,必须放在设置编码和格式的后面，否则报错
                mRecorder.setVideoFrameRate(30);//这是设置视频录制的帧率，即1秒钟30帧。。必须放在设置编码和格式的后面，否则报错
                mRecorder.setVideoEncodingBitRate(4 * 1024 * 1024);//这个属性很重要，这个也直接影响到视频录制的大小，这个设置的越大，视频越清晰
                mRecorder.setOrientationHint(rotationRecord);//视频旋转90度
                mRecorder.setMaxDuration(maxDuration * 1000);//设置录制最长时间为15秒
                mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());//设置录制视频时的预览画面
                path = getSdPath();
                if (path != null) {
                    File dir = new File(path + "/DCIM/Camera");
                    if (!dir.exists()) {
                        dir.mkdir();
                    }
                    path = dir + "/" + System.currentTimeMillis() + ".mp4";
                    mRecorder.setOutputFile(path);// 设置视频文件输出的路径
                    mRecorder.prepare();// 准备录制
                    mRecorder.start();// 开始录制
                    text = 0;//当点击停止之后，每一次进到这里都要重置录制的时间数
                    handler.postDelayed(runnable, 1000);
                    time.setVisibility(View.VISIBLE);
                    state = 1;//开始录制
                    setBntState();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void stopRecord() {
        try {
            handler.removeCallbacks(runnable);
            time.setVisibility(View.GONE);//隐藏时间
            mRecorder.stop();// 停止录制
            mRecorder.reset();// 恢复到未初始化的状态
            mRecorder.release();// 释放资源
            mRecorder = null;
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }
            File file = new File(path);
            saveVideo(VideoActivity.this, file);

            Matrix matrix = new Matrix();
            Bitmap bitmap = getVideoThumb(path);
//            if (rotationFlag != 0) {
//                matrix.setRotate(rotationFlag);
//                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
//                        bitmap.getHeight(), matrix, true);
//            }
//            Drawable drawable = new BitmapDrawable(getResources(), bitmap);
//            surfaceView.setBackground(drawable);
            surfaceView.setBackgroundColor(Color.rgb(0, 0, 0));
            thumb.setImageBitmap(bitmap);
            thumb.setVisibility(View.VISIBLE);
            state = 2;
            setBntState();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取SD path
     *
     * @return
     */
    public String getSdPath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);//判断sd卡是否存在
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();//获取根目录
            return sdDir.toString();
        }
        return null;
    }

    public static Bitmap getVideoThumb(String path) {
        Reference<MediaMetadataRetriever> retriever = new WeakReference<>(new MediaMetadataRetriever());
        retriever.get().setDataSource(path);
        String duration = retriever.get().extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        return retriever.get().getFrameAtTime(Integer.parseInt(duration) * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
    }

    /**
     * 保存视频
     *
     * @param context
     * @param file
     */
    public static void saveVideo(Context context, File file) {
        //是否添加到相册
        ContentResolver localContentResolver = context.getContentResolver();
        ContentValues localContentValues = getVideoContentValues(context, file, System.currentTimeMillis());
        Uri localUri = localContentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, localContentValues);
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri));
    }

    public static ContentValues getVideoContentValues(Context paramContext, File paramFile, long paramLong) {
        ContentValues localContentValues = new ContentValues();
        localContentValues.put("title", paramFile.getName());
        localContentValues.put("_display_name", paramFile.getName());
        localContentValues.put("mime_type", "video/mp4");
        localContentValues.put("datetaken", Long.valueOf(paramLong));
        localContentValues.put("date_modified", Long.valueOf(paramLong));
        localContentValues.put("date_added", Long.valueOf(paramLong));
        localContentValues.put("_data", paramFile.getAbsolutePath());
        localContentValues.put("_size", Long.valueOf(paramFile.length()));
        return localContentValues;
    }
}
